#ifndef __INETADDR_HPP__
#define __INETADDR_HPP__

#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string>
#include<string.h>

class InetAddr
{
private:    
    void Net2Host()
    {
        char buffer[64];
        // _ip = inet_ntoa(_addr.sin_addr);
        inet_ntop(AF_INET , &(_addr.sin_addr) , buffer , sizeof(buffer));
        _ip = buffer;
        _port = ntohs(_addr.sin_port);
    }
    void Host2Net()
    {
        memset(&_addr , 0 , sizeof(_addr));
        _addr.sin_family = AF_INET;
        _addr.sin_port = htons(_port);
        // _addr.sin_addr.s_addr = inet_addr(_ip.c_str());
        inet_pton(AF_INET , _ip.c_str() ,&(_addr.sin_addr));
    }
public:
    InetAddr(){}

    //两种构造
    //使用网络地址构造 ，需要注意网络转主机
    InetAddr(struct sockaddr_in& addr):_addr(addr)
    {
        Net2Host();
    }

    //传入port , 初始化网络地址;同时需要注意主机转网络
    InetAddr(uint16_t port , std::string ip = "0.0.0.0")
    :_port(port)
    ,_ip(ip)
    {
        Host2Net();
    }

    void Init(const struct sockaddr_in& addr)
    {
        _addr = addr;
        Net2Host();//网络转主机
    }

    //get接口
    struct sockaddr* Addr()
    {
        return (struct sockaddr*)&_addr;
    }
    std::string Ip()
    {
        return _ip;
    }
    uint16_t Port()
    {
        return _port;
    }
    socklen_t Length()
    {
        return sizeof(_addr);
    }

    //方便debug
    std::string ToString()
    {
        return _ip + '-' + std::to_string(_port);
    }

    //支持地址的比较，重载==
    bool operator==(InetAddr&addr)
    {
        //比较ip  和端口
        return _ip==addr._ip && _port==addr._port;
    }
    bool operator==(const InetAddr&addr)
    {
        return _ip==addr._ip && _port==addr._port;
    }
private:
    struct sockaddr_in _addr;
    std::string _ip;
    uint16_t _port;
};

#endif